﻿Imports System.Text.RegularExpressions

Public Class Calcolatrice
  Private flagPuntoDecimale As Boolean = False
  Private cNastro As clsNastro
  Private Valore As Double = 0
  ' dichiara un oggetto PrintDocument
  ' di nome documento (per anteprima)
  Private WithEvents documento _
    As New System.Drawing.Printing.PrintDocument

  Private Sub Calcolatrice_Load(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles MyBase.Load
    cNastro =
      New clsNastro(Me.Nastro)
    InizializzaPrintPreviewDialog()
  End Sub

  Private Sub Tasto1_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles Tasto1.Click
    premiTastoNumerico("1")
  End Sub

  Private Sub Tasto2_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles Tasto2.Click
    premiTastoNumerico("2")
  End Sub

  Private Sub Tasto3_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles Tasto3.Click
    premiTastoNumerico("3")
  End Sub

  Private Sub Tasto4_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles Tasto4.Click
    premiTastoNumerico("4")
  End Sub

  Private Sub Tasto5_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles Tasto5.Click
    premiTastoNumerico("5")
  End Sub

  Private Sub Tasto6_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles Tasto6.Click
    premiTastoNumerico("6")
  End Sub

  Private Sub Tasto7_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles Tasto7.Click
    premiTastoNumerico("7")
  End Sub

  Private Sub Tasto8_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles Tasto8.Click
    premiTastoNumerico("8")
  End Sub

  Private Sub Tasto9_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles Tasto9.Click
    premiTastoNumerico("9")
  End Sub

  Private Sub Tasto0_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles Tasto0.Click
    premiTastoNumerico("0")
  End Sub

  Private Sub premiTastoNumerico(
      ByVal tastoNumerico As String)
    Display.Text =
      Display.Text & tastoNumerico
    Me.Display.Focus()
    Me.Display.SelectionStart =
      Me.Display.Text.Length
  End Sub

  Private Sub Display_KeyPress(
      ByVal sender As Object, ByVal e As  _
      System.Windows.Forms.KeyPressEventArgs) _
      Handles Display.KeyPress
    Dim tasto As New Control
    Select Case e.KeyChar
      Case "1"c, "2"c, "3"c, "4"c, "5"c,
           "6"c, "7"c, "8"c, "9"c, "0"c
        premiTastoNumerico(e.KeyChar)
      Case "."c
        Call Me.PuntoDecimale_Click(sender, e)
      Case "+"c
        Call Me.TastoPiu_Click(sender, e)
      Case "-"c
        Call Me.TastoMeno_Click(sender, e)
      Case "*"c
        Call Me.TastoPer_Click(sender, e)
      Case "/"c
        Call Me.TastoDiviso_Click(sender, e)
      Case "="c
        Call Me.TastoUguale_Click(sender, e)
      Case Else
        ' non fa nulla
    End Select
    Me.Display.Focus()
    Me.Display.SelectionStart =
      Me.Display.Text.Length
  End Sub

  Private Sub Tasto000_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles Tasto000.Click
    Display.Text = Display.Text & "000"
    Me.Display.Focus()
    Me.Display.SelectionStart =
      Me.Display.Text.Length
  End Sub

  Private Sub PuntoDecimale_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles PuntoDecimale.Click
    If flagPuntoDecimale = False Then
      Display.Text = Display.Text & ","
      flagPuntoDecimale = True
    End If
    Me.Display.Focus()
    Me.Display.SelectionStart =
      Me.Display.Text.Length
  End Sub

  Private Sub TastoC_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles TastoC.Click
    Display.Text = ""
    flagPuntoDecimale = False
    Me.Display.Focus()
  End Sub

  Private Sub TastoCE_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles TastoCE.Click
    Call cNastro.AzzeraNastro()
    Call cNastro.SvuotaNastro()
    Call cNastro.AggiornaNastro()
    Display.Text = ""
    flagPuntoDecimale = False
    Valore = 0
    Me.Display.Focus()
    Me.Display.SelectionStart =
      Me.Display.Text.Length
  End Sub

  Private Sub TastoCancellaUno_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles TastoCancellaUno.Click
    If Display.Text.Substring(
        Display.Text.Length - 1, 1) = "," Then
      flagPuntoDecimale = False
    End If
    Display.Text =
      Display.Text.Substring(
        0, Display.Text.Length - 1)
    Me.Display.Focus()
    Me.Display.SelectionStart =
      Me.Display.Text.Length
  End Sub

  Private Sub TastoPiu_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles TastoPiu.Click
    Call eseguiOperazione("+")
  End Sub

  Private Sub TastoMeno_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles TastoMeno.Click
    Call eseguiOperazione("-")
  End Sub

  Private Sub TastoPer_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles TastoPer.Click
    Call eseguiOperazione("*")
  End Sub

  Private Sub TastoDiviso_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles TastoDiviso.Click
    Call eseguiOperazione("/")
  End Sub

  Private Sub eseguiOperazione(
      ByVal operatore As String)
    Select Case operatore
      Case "+"
        Valore +=
          CType(Display.Text, Double)
        Call cNastro.Inserisci(
          Display.Text, "+")
      Case "-"
        Valore -= CType(
          Display.Text, Double)
        Call cNastro.Inserisci(
          Display.Text, "-")
      Case "*"
        Valore *= CType(
          Display.Text, Double)
        Call cNastro.Inserisci(
          Display.Text, "*")
      Case "/"
        Valore /= CType(
          Display.Text, Double)
        Call cNastro.Inserisci(
          Display.Text, "/")
    End Select
    Display.Text = ""
    flagPuntoDecimale = False
    Me.Display.Focus()
  End Sub

  Private Sub TastoUguale_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles TastoUguale.Click
    Call cNastro.Inserisci(
      Valore.ToString, "=")
    Display.Text = CType(Valore, String)
    Valore = 0
    flagPuntoDecimale = False
    Call cNastro.SvuotaNastro()
    Call cNastro.AggiornaNastro()
    Me.Display.Focus()
    Me.Display.SelectionStart =
      Me.Display.Text.Length
  End Sub

  Private Sub TastoSalva_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles TastoSalva.Click
    Dim nomeFile As String = ""
    SaveFileDialog1.InitialDirectory =
      "c:\"
    SaveFileDialog1.FileName =
      "C:\prova.txt"
    SaveFileDialog1.Filter =
      "file di testo (*.txt)|*.txt"
    SaveFileDialog1.FilterIndex = 1
    SaveFileDialog1.RestoreDirectory =
      True
    If SaveFileDialog1.ShowDialog() =
        Windows.Forms.DialogResult.OK Then
      nomeFile =
        Me.SaveFileDialog1.FileName
      cNastro.SalvaNastro(nomeFile)
    End If
    Me.Display.Focus()
    Me.Display.SelectionStart =
      Me.Display.Text.Length
  End Sub

  Private Sub TastoRecupera_Click(
      ByVal sender As System.Object,
      ByVal e As System.EventArgs) _
      Handles TastoRecupera.Click
    OpenFileDialog1.InitialDirectory =
      "c:\"
    OpenFileDialog1.FileName =
      "C:\prova.txt"
    OpenFileDialog1.Filter =
      "file di testo (*.txt)|*.txt"
    OpenFileDialog1.FilterIndex = 1
    OpenFileDialog1.RestoreDirectory =
      True
    If OpenFileDialog1.ShowDialog() =
        Windows.Forms.DialogResult.OK Then
      Dim nomeFile As String =
        Me.OpenFileDialog1.FileName
      cNastro.RecuperaNastro(nomeFile)
    End If
    Me.Display.Focus()
    Me.Display.SelectionStart =
      Me.Display.Text.Length
  End Sub

  Private Sub InizializzaPrintPreviewDialog()
    ' imposta dimensione, posizione e nome
    Me.PrintPreviewDialog1.ClientSize =
      New System.Drawing.Size(400, 500)
    Me.PrintPreviewDialog1.Location =
      New System.Drawing.Point(29, 29)
    Me.PrintPreviewDialog1.Name =
      "PrintPreviewDialog1"
    ' imposta la dimensione minima
    ' della finestra di dialogo
    Me.PrintPreviewDialog1.MinimumSize =
      New System.Drawing.Size(375, 250)
    ' imposta la proprietà UseAntiAlias a True
    ' per permettere al sistema operativo di
    ' utilizzare l'effetto antialiasing
    Me.PrintPreviewDialog1.UseAntiAlias =
      True
  End Sub

  Private Sub TastoAnteprima_Click(
      ByVal sender As Object,
      ByVal e As System.EventArgs) _
      Handles TastoAnteprima.Click
    Me.TestoDaStampare.Text =
      cNastro.componiNastro
    ' imposta la proprietà 
    ' PrintPreviewDialog.Document all'oggetto
    ' PrintDocument selezionato dall'utente
    PrintPreviewDialog1.Document =
      documento
    ' chiama il metodo ShowDialog che
    ' scatenerà l'evento PrintPage del
    ' documento
    PrintPreviewDialog1.ShowDialog()
    Me.Display.Focus()
    Me.Display.SelectionStart =
      Me.Display.Text.Length
  End Sub

  Private Sub documento_PrintPage(
      ByVal sender As Object,
      ByVal e As  _
      System.Drawing.Printing.PrintPageEventArgs) _
      Handles documento.PrintPage
    '' Qui va inserito il codice per disegnare
    '' la pagina. Questo codice sarà chiamato da
    '' PrintPreviewDialog.Show 
    ' Il seguente codice prepara un semplice messaggio
    ' sul documento creato nella finestra di dialogo
    Dim text As String =
      formattaStampa(Me.TestoDaStampare.Text)
    Dim printFont As New System.Drawing.Font(
        "Courier New", 14,
        System.Drawing.FontStyle.Regular)
    e.Graphics.DrawString(
      text, printFont,
      System.Drawing.Brushes.Black, 500, 100)
  End Sub

  Private Function formattaStampa(
      ByVal testoNastro As String) _
      As String
    Dim expreg As New Regex(
      Environment.NewLine)
    Dim arrayStampa() As String =
      Regex.Split(
        testoNastro, Environment.NewLine)
    Dim riga As String = ""
    Dim spazi As String =
      "                      "   ' 22 spazi
    Dim i As Integer
    For i = 0 To arrayStampa.GetUpperBound(0)
      riga = arrayStampa(i)
      riga = spazi & riga
      riga = riga.Substring(
        riga.Length - 22, 22)
      arrayStampa(i) = riga
    Next
    testoNastro = arrayStampa(0)
    For i = 1 To arrayStampa.GetUpperBound(0)
      testoNastro &=
        Environment.NewLine & arrayStampa(i)
    Next
    Return testoNastro
  End Function
End Class

